Skip to content

Finally 1 ​

本节目标:理解“Finally 1”的核心思路,并能把它用于实际开发或面试表达。 finally可以透传值,即: finally的参数函数如果返回一个promise:

  • 如果这个promise成功了,finally.then的成功回调会执行,但传递给成功回调的成功值为调用finally的promsie的成功值,而不是finally函数返回的promise的成功值;即finally函数的返回值会被丢弃;
  • 如果这个promise失败了,finally.then的失败回调会执行,传递给失败回调的失败原因为这个promise的reject的失败原因;

实现: finally在promise状态不管是成功还是失败时,都要执行,理论上,我们可以在成功回调和失败回调中执行同样的代码来实现;但是由于要实现透传,所以不能简单地使用then(finallyArgFn,finallyArgFn)来实现;

Promise.prototype.finally

= function

(cb)

{return

this.then((y)

=\> {return

Promise.resolve(cb()).then(()

=\>

y)
 `},`
(r)

=\> {return

Promise.resolve(cb()).then(()

=\> { throw r }); // 因为finally的promise执行出错, 会导致不会执行Promise.resolve的正常逻辑 ,所以以finally错误为结果

})
}
Promise.resolve('ok').finally(()

=\> { // finally 并不会影响最终的结果 return new

Promise((resolve,
reject)

=\> {

setTimeout(()

=\> {

resolve('inner
ok')
     `},`
1000);
})
}).then((data)

=\> {

console.log('

成功

',
data)
},
(err)

=\> {

console.log('

失败

',
err)
})
  • finally在内部是调用了this.then函数,.then函数会返回一个promise,我们将这个promise作为finally的返回值返回出来,所以,finally后面是可以链式调用的;
  • 当.finally时,表示对当前的promise使用then方法添加一个成功回调和失败回调;
  • 并且成功的回调函数和失败的回调函数内部都调用了Promise.resolve方法;
  • 这个方法是是创建了一个promise对象,并且具有等待效果的;所以,我们可以利用then给它添加成功回调和失败回调的;
  • 但我们这里只定义了成功回调,成功回调只是透传finally前的成功值;如果finally的回调函数返回的promise对象状态是reject,相当于Promise.resolve这个promise状态失败,会调用then方法的失败回调,由于我们没有定义失败回调,是不会有任何反应的;
  • 这意味着,成功和失败的回调会等待finally的参数函数的执行结果,如果finally参数返回一个promise,是会等待这个promise的;